package parsers;

import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import smXmlMapping.Exame;
import smXmlMapping.PacienteXML;
import smXmlMapping.Resultado;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class SMXMLParser {

    //No generics
    private Document dom;
    private String nomeArquivo;

    public SMXMLParser() {
        
    }
    public SMXMLParser(String nomeArquivo) {
        
        this.nomeArquivo = nomeArquivo;
    }
    
    public void mapXmlFile() {
        //get the factory
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            //Using factory get an instance of document builder
            DocumentBuilder db = dbf.newDocumentBuilder();


            //File f = new File("RES_21102009_1456_OS_10912695.xml");
            File f = new File(nomeArquivo);

            if (!f.exists()) {
                System.out.println("Documento não encontrado");
                System.exit(1);
            }

            //parse using builder to get DOM representation of the XML file
            setDom(db.parse(f));

            
            


        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (SAXException se) {
            se.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public void mapXmlFile(InputStream is){
        //get the factory
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            //Using factory get an instance of document builder
            DocumentBuilder db = dbf.newDocumentBuilder();
            
            //parse using builder to get DOM representation of the XML file
            setDom(db.parse(is));


        } catch (SAXException ex) {
            Logger.getLogger(SMXMLParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public ArrayList<Exame> extractExames() {
        //get the root elememt
        ArrayList<Exame> exames = new ArrayList<Exame>();

        Element docEle = getDom().getDocumentElement();

        //get a nodelist of <employee> elements
        NodeList nl = docEle.getElementsByTagName("exame");

        for (int i = 0; i < nl.getLength(); i++) {
            //get the employee element
            Element el = (Element) nl.item(i);

            //get the Employee object
            Exame e = getExame(el);

            //add it to list
            exames.add(e);
        }

        return exames;
    }

    public PacienteXML parseUser() throws NullPointerException{

        PacienteXML pacienteXML = new PacienteXML();
        try{
        
        Element docEle = getDom().getDocumentElement();
        NodeList nl2 = docEle.getElementsByTagName("solicitacao");
        Element el = (Element) nl2.item(0);
        pacienteXML.setPaciente(el.getAttribute("paciente"));
        pacienteXML.setNomePaciente(el.getAttribute("nome_paciente"));
        }catch(NullPointerException nil){
            throw nil;
        }

        return pacienteXML;

    }

    /**
     * I take an employee element and read the values in, create
     * an Exame object and return it
     * @param empEl
     * @return
     */
    private Exame getExame(Element empEl) {

        Exame exame = new Exame();
        
        byte[] utf8 = null;

        //get a nodelist of <employee> elements
        NodeList nl = empEl.getElementsByTagName("resultado");

        for (int i = 0; i < nl.getLength(); i++) {
            
                Element el = (Element) nl.item(i);
                Resultado resultado = new Resultado();

                resultado.setAmostra(el.getAttribute("amostra"));
//                utf8 = new String(el.getAttribute("amostra").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));

                resultado.setAtributo(el.getAttribute("atributo"));
//                utf8 = new String(el.getAttribute("atributo").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));

                resultado.setLinhaResultado(el.getAttribute("linharesultado"));
//                utf8 = new String(el.getAttribute("linharesultado").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));


                resultado.setMetodo(el.getAttribute("metodo"));
//                utf8 = new String(el.getAttribute("metodo").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));


                resultado.setResultado(el.getAttribute("resultado"));
//                utf8 = new String(el.getAttribute("resultado").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));


                resultado.setConclusao(el.getAttribute("conclusao"));
//                utf8 = new String(el.getAttribute("conclusao").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));


                resultado.setStatus(el.getAttribute("status"));
//                utf8 = new String(el.getAttribute("status").getBytes(), "ISO-8859-1").getBytes("UTF-8");
//                resultado.setAmostra(new String(utf8));


                exame.getResultados().add(resultado);
        }
           
       
        exame.setCodigo(empEl.getAttribute("codigo"));
        exame.setNome(empEl.getAttribute("nome"));
        exame.setDataResultado(empEl.getAttribute("dataresultado"));

        return exame;
    }

    /**
     * I take a xml element and the tag name, look for the tag and get
     * the text content
     * i.e for <employee><name>John</name></employee> xml snippet if
     * the Element points to employee node and tagName is name I will return John
     * @param ele
     * @param tagName
     * @return
     */
    private String getTextValue(Element ele, String tagName) {
        String textVal = null;
        NodeList nl = ele.getElementsByTagName(tagName);
        if (nl != null && nl.getLength() > 0) {
            Element el = (Element) nl.item(0);
            textVal = el.getFirstChild().getNodeValue();
        }

        return textVal;
    }

    /**
     * Calls getTextValue and returns a int value
     * @param ele
     * @param tagName
     * @return
     */
    private int getIntValue(Element ele, String tagName) {
        //in production application you would catch the exception
        return Integer.parseInt(getTextValue(ele, tagName));
    }

     /**
     * @return the dom
     */
    public Document getDom() {
        return dom;
    }

    /**
     * @param dom the dom to set
     */
    public void setDom(Document dom) {
        this.dom = dom;
    }

}
